package vn.bang.xiangqi.server.thread;

import java.util.Collection;
import java.util.Map;
import java.util.Queue;

import vn.bang.communication.Command;
import vn.bang.communication.Command.CommandName;
import vn.bang.communication.Communicator;
import vn.bang.entity.GameDTO;
import vn.bang.entity.PlayerDTO;
import vn.bang.entity.UserDTO;
import vn.bang.utility.DateUtil;
import vn.bang.utility.StringUtil;
import vn.bang.xiangqi.server.business.LoginBusiness;
import vn.bang.xiangqi.server.log.Log;

public class CommandProcessorThread extends BaseThread {

	private Map<Integer, Map<Long, Communicator>> communicators;
	private Collection<GameDTO> games;
	private Queue<Command> commandQueue;
	private Collection<PlayerDTO> players;
	
	public CommandProcessorThread(Queue<Command> commandQueue, Map<Integer, Map<Long, Communicator>> communicators, Collection<GameDTO> games, Collection<PlayerDTO> players) {
		this.commandQueue = commandQueue;
		this.communicators = communicators;
		this.games = games;
		this.players = players;
		
		this.setProcessor(new IProcess() {
			
			public void process() {
				Command command = pollCommandFromQueue();
				processCommand(command);
			}
		});
	}
	
	private Command pollCommandFromQueue() {
		if (null == commandQueue || commandQueue.isEmpty()) {
			return null;
		}
		return commandQueue.poll();
	}
	
	private void processCommand(Command command) {
		if (null == command) {
			return;
		}
		Log.info("process command");
		if (CommandName.NEW_GAME.toString().equals(command.getName())) {
			processNewGame(command);
		} else if (CommandName.MOVE.toString().equals(command.getName())) {
			processMove(command);
		} else if (CommandName.LOGIN.toString().equals(command.getName())) {
			processLogin(command);
		}
	}
	
	private void processLogin(Command command) {
		String username = command.getParameters()[0];
		String password = command.getParameters()[1];
		login(username, password);
	}
	
	private void login(String username, String password) {
		UserDTO user = LoginBusiness.login(username, password);
		if (null != user) { // login successfully
			addPlayer(user.getPlayer());
			Log.info(String.format("Player '%s' is logined", user.getUsername()));
		}
	}
	
	private void addPlayer(PlayerDTO player) {
		players.add(player);
	}
	
	private void processNewGame(Command command) {
		if (StringUtil.isNullOrEmpty(command.getParameters()[0])
				|| StringUtil.isNullOrEmpty(command.getParameters()[1])) {
			Log.error("Parameters invalid!");
			return;
		}
		
		long hostId;
		long playerId;
		
		try {
			hostId = Long.parseLong(command.getParameters()[0]);
			playerId = Long.parseLong(command.getParameters()[1]);
		} catch (NumberFormatException numberFormatException) {
			Log.error("Parameters must be a long number!");
			return;
		}
		
		GameDTO game = newGame(hostId, playerId);
		Communicator clientCommunicator = getClientCommunicators(game.getPlayers());
		sendNewGameMessageToClients(clientCommunicator);
	}
	
	private GameDTO newGame(long hostId, long playerId) {
//		GameBean game = new GameBean(hostId, playerId);
		GameDTO game = new GameDTO();
		games.add(game);
		return game;
	}

	private Communicator getClientCommunicators(Collection<PlayerDTO> players) {
		Communicator communicator = null;
		//TODO
		
		return communicator;
	}

	private void sendNewGameMessageToClients(Communicator communicator) {
		// TODO Auto-generated method stub
	}

	private void processMove(Command command) {
		// TODO Auto-generated method stub
	}
}
